home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / LIB / GLE / TEXGEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  11.3 KB  |  405 lines

  1.  
  2. /*
  3.  * texgen.c
  4.  *
  5.  * FUNCTION:
  6.  * texture mapping hack
  7.  *
  8.  * HISTORY:
  9.  * Created by Linas Vepstas April 1994
  10.  * general cleanup December 1995
  11.  */
  12.  
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include <GL/tube.h>
  16. #include "port.h"
  17. #include "tube_gc.h"
  18.  
  19. /* ======================================================= */
  20.  
  21. gleGC *_gle_gc = 0x0;
  22.  
  23. gleGC * gleCreateGC (void) {
  24.    gleGC * retval = (gleGC *) malloc (sizeof (gleGC));
  25.  
  26.    retval -> bgn_gen_texture = 0x0;
  27.    retval -> n3f_gen_texture = 0x0;
  28.    retval -> n3d_gen_texture = 0x0;
  29.    retval -> v3f_gen_texture = 0x0;
  30.    retval -> v3d_gen_texture = 0x0;
  31.    retval -> end_gen_texture = 0x0;
  32.  
  33.    retval -> save_bgn_gen_texture = 0x0;
  34.    retval -> save_n3f_gen_texture = 0x0;
  35.    retval -> save_n3d_gen_texture = 0x0;
  36.    retval -> save_v3f_gen_texture = 0x0;
  37.    retval -> save_v3d_gen_texture = 0x0;
  38.    retval -> save_end_gen_texture = 0x0;
  39.  
  40.    retval -> join_style = TUBE_JN_ANGLE | TUBE_JN_CAP | TUBE_NORM_FACET;
  41.    retval -> ncp = 0;
  42.    retval -> npoints = 0;
  43.  
  44.    retval -> num_vert = 0;
  45.    retval -> segment_number = 0;
  46.    retval -> segment_length = 0.0;
  47.    retval -> accum_seg_len = 0.0;
  48.    retval -> prev_x = 0.0;
  49.    retval -> prev_y = 0.0;
  50.  
  51.    return retval;
  52. }
  53.  
  54. /* ======================================================= */
  55.  
  56. #define segment_number (_gle_gc -> segment_number)
  57. #define segment_length (_gle_gc -> segment_length)
  58. #define accum_seg_len (_gle_gc -> accum_seg_len)
  59. #define num_vert  (_gle_gc -> num_vert)
  60. #define prev_x  (_gle_gc -> prev_x)
  61. #define prev_y  (_gle_gc -> prev_y)
  62.  
  63. /* ======================================================= */
  64.  
  65. static double save_nx = 0.0;
  66. static double save_ny = 0.0;
  67. static double save_nz = 0.0;
  68.  
  69. static void save_normal (double *v) {
  70.    save_nx = v[0];
  71.    save_ny = v[1];
  72.    save_nz = v[2];
  73. }
  74.  
  75. /* ======================================================= */
  76.  
  77. static void bgn_sphere_texgen (int inext, double len) {
  78.    segment_number = inext - 1;
  79.    segment_length = len;
  80.    num_vert = 0;
  81. }
  82.  
  83. /* ======================================================= */
  84. /* 
  85.  * this routine assumes that the vertex passed in has been normalized
  86.  * (i.e. is of unit length)
  87.  */
  88. /* ARGSUSED3 */
  89. static void sphere_texgen (double x, double y, double z,
  90.                            int jcnt, int which_end) 
  91. {
  92.    double theta, phi;
  93.  
  94.    /* let phi and theta range fro 0 to 1 */
  95.    phi = 0.5 * atan2 (x, y) / M_PI;
  96.    phi += 0.5;
  97.  
  98.    theta = 1.0 - acos (z) / M_PI;
  99.  
  100.    /* if first vertex, merely record the texture coords */
  101.    if (num_vert == 0) {
  102.       prev_x = phi;
  103.       prev_y = theta;
  104.       num_vert ++;
  105.    } else {
  106.  
  107.       /* if texture coordinates changed radically, wrap them */
  108.       if ((prev_y - theta) > 0.6) {
  109.          theta +=1.0;
  110.       } else if ((prev_y - theta) < -0.6) {
  111.          theta -=1.0;
  112.       } /* else no-op */
  113.       prev_y = theta;
  114.  
  115.  
  116.       /* if texture coordinates changed radically, wrap them */
  117.       if ((prev_x - phi) > 0.6) {
  118.          phi +=1.0;
  119.       } else if ((prev_x - phi) < -0.6) {
  120.          phi -=1.0;
  121.       } /* else no-op */
  122.       prev_x = phi;
  123.  
  124.    }
  125.  
  126.    T2F_D (phi, theta);
  127. }
  128.  
  129. /* ======================================================= */
  130. /* mappers */
  131.  
  132. static void vertex_sphere_texgen_v (double *v, int jcnt, int which_end)  {
  133.    double x = v[0]; double y = v[1]; double z = v[2];
  134.    double r;
  135.  
  136.    r = 1.0 / sqrt (x*x + y*y + z*z);
  137.    x *= r;
  138.    y *= r;
  139.    z *= r;
  140.    sphere_texgen (x, y, z, jcnt, which_end);
  141. }
  142.  
  143. /* ARGSUSED */
  144. static void normal_sphere_texgen_v (double *v, int jcnt, int which_end)  {
  145.    sphere_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  146. }
  147.  
  148. static void vertex_sphere_model_v (double *v, int jcnt, int which_end) {
  149.    double x = _gle_gc->contour[jcnt][0]; 
  150.    double y = _gle_gc->contour[jcnt][1]; 
  151.    double z = v[2];
  152.    double r;
  153.  
  154.    r = 1.0 / sqrt (x*x + y*y + z*z);
  155.    x *= r;
  156.    y *= r;
  157.    z *= r;
  158.    sphere_texgen (x, y, z, jcnt, which_end);
  159. }
  160.  
  161. /* ARGSUSED */
  162. static void normal_sphere_model_v (double *v, int jcnt, int which_end) {
  163.    if (!(_gle_gc -> cont_normal)) return;
  164.    sphere_texgen (_gle_gc->cont_normal[jcnt][0], 
  165.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  166. }
  167.  
  168. /* ======================================================= */
  169.  
  170. static void bgn_z_texgen (int inext, double len) {
  171.  
  172.    /* accumulate the previous length */
  173.    accum_seg_len += segment_length;
  174.  
  175.    /* save current values */
  176.    segment_number = inext - 1;
  177.    segment_length = len;
  178.  
  179.    /* reset counter on first segment */
  180.    if (1 >= segment_number) accum_seg_len = 0.0;
  181.  
  182.    num_vert = 0;
  183. }
  184.  
  185. /* ======================================================= */
  186.  
  187. /* ARGSUSED2 */
  188. static void cylinder_texgen (double x, double y, double z,
  189.                              int jcnt, int which_end) 
  190. {
  191.    double phi;
  192.  
  193.    /* let phi and theta range fro 0 to 1 */
  194.    phi = 0.5 * atan2 (x, y) / M_PI;
  195.    phi += 0.5;
  196.  
  197.    /* if first vertex, merely record the texture coords */
  198.    if (num_vert == 0) {
  199.       prev_x = phi;
  200.       num_vert ++;
  201.    } else {
  202.       /* if texture coordinates changed radically, wrap them */
  203.       if ((prev_x - phi) > 0.6) {
  204.          phi +=1.0;
  205.       } else if ((prev_x - phi) < -0.6) {
  206.          phi -=1.0;
  207.       } /* else no-op */
  208.       prev_x = phi;
  209.    }
  210.  
  211.    if (FRONT == which_end) {
  212.       T2F_D (phi, accum_seg_len);
  213.    }
  214.    if (BACK == which_end) {
  215.       T2F_D (phi, accum_seg_len + segment_length);
  216.    }
  217. }
  218.  
  219. /* ======================================================= */
  220. /* mappers */
  221.  
  222. static void vertex_cylinder_texgen_v (double *v, int jcnt, int which_end) {
  223.    double x = v[0]; double y = v[1]; double z = v[2];
  224.    double r;
  225.  
  226.    r = 1.0 / sqrt (x*x + y*y);
  227.    x *= r;
  228.    y *= r;
  229.    cylinder_texgen (x, y, z, jcnt, which_end);
  230. }
  231.  
  232. /* ARGSUSED */
  233. static void normal_cylinder_texgen_v (double *v, int jcnt, int which_end) {
  234.    cylinder_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  235. }
  236.  
  237. static void vertex_cylinder_model_v (double *v, int jcnt, int which_end) {
  238.    double x = _gle_gc->contour[jcnt][0]; 
  239.    double y = _gle_gc->contour[jcnt][1]; 
  240.    double z = v[2];
  241.    double r;
  242.  
  243.    r = 1.0 / sqrt (x*x + y*y);
  244.    x *= r;
  245.    y *= r;
  246.    cylinder_texgen (x, y, z, jcnt, which_end);
  247. }
  248.  
  249. /* ARGSUSED */
  250. static void normal_cylinder_model_v (double *v, int jcnt, int which_end) {
  251.    if (!(_gle_gc -> cont_normal)) return;
  252.    cylinder_texgen (_gle_gc->cont_normal[jcnt][0], 
  253.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  254. }
  255.  
  256. /* ======================================================= */
  257.  
  258. /* ARGSUSED1 */
  259. static void flat_texgen (double x, double y, double z,
  260.                              int jcnt, int which_end) 
  261. {
  262.    if (FRONT == which_end) {
  263.       T2F_D (x, accum_seg_len);
  264.    }
  265.    if (BACK == which_end) {
  266.       T2F_D (x, accum_seg_len + segment_length);
  267.    }
  268. }
  269.  
  270. /* ======================================================= */
  271.  
  272.  
  273. static void vertex_flat_texgen_v (double *v, int jcnt, int which_end) {
  274.    flat_texgen (v[0], v[1], v[2], jcnt, which_end);
  275. }
  276.  
  277. /* ARGSUSED */
  278. static void normal_flat_texgen_v (double *v, int jcnt, int which_end) {
  279.    flat_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  280. }
  281.  
  282. static void vertex_flat_model_v (double *v, int jcnt, int which_end) {
  283.    flat_texgen (_gle_gc->contour[jcnt][0], 
  284.                 _gle_gc->contour[jcnt][1], v[2], jcnt, which_end);
  285. }
  286.  
  287. /* ARGSUSED */
  288. static void normal_flat_model_v (double *v, int jcnt, int which_end) {
  289.    if (!(_gle_gc -> cont_normal)) return;
  290.    flat_texgen (_gle_gc->cont_normal[jcnt][0], 
  291.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  292. }
  293.  
  294. /* ======================================================= */
  295.  
  296. void gleTextureMode (int mode) {
  297.  
  298.    INIT_GC();
  299.  
  300.    /* enable textureing by restoring the mode */
  301.    _gle_gc -> bgn_gen_texture = _gle_gc -> save_bgn_gen_texture; 
  302.    _gle_gc -> n3f_gen_texture = _gle_gc -> save_n3f_gen_texture; 
  303.    _gle_gc -> n3d_gen_texture = _gle_gc -> save_n3d_gen_texture; 
  304.    _gle_gc -> v3f_gen_texture = _gle_gc -> save_v3f_gen_texture; 
  305.    _gle_gc -> v3d_gen_texture = _gle_gc -> save_v3d_gen_texture; 
  306.    _gle_gc -> end_gen_texture = _gle_gc -> save_end_gen_texture; 
  307.  
  308.    switch (mode&GLE_TEXTURE_STYLE_MASK) {
  309.  
  310.       case GLE_TEXTURE_VERTEX_FLAT:
  311.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  312.          _gle_gc -> v3d_gen_texture = vertex_flat_texgen_v;
  313.          _gle_gc -> n3d_gen_texture = 0x0;
  314.          break;
  315.  
  316.       case GLE_TEXTURE_NORMAL_FLAT:
  317.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  318.          _gle_gc -> v3d_gen_texture = normal_flat_texgen_v;
  319.          _gle_gc -> n3d_gen_texture = save_normal;
  320.          break;
  321.  
  322.       case GLE_TEXTURE_VERTEX_MODEL_FLAT:
  323.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  324.          _gle_gc -> v3d_gen_texture = vertex_flat_model_v;
  325.          _gle_gc -> n3d_gen_texture = 0x0;
  326.          break;
  327.  
  328.       case GLE_TEXTURE_NORMAL_MODEL_FLAT:
  329.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  330.          _gle_gc -> v3d_gen_texture = normal_flat_model_v;
  331.          _gle_gc -> n3d_gen_texture = 0x0;
  332.          break;
  333.  
  334.       case GLE_TEXTURE_VERTEX_CYL:
  335.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  336.          _gle_gc -> v3d_gen_texture = vertex_cylinder_texgen_v;
  337.          _gle_gc -> n3d_gen_texture = 0x0;
  338.          break;
  339.  
  340.       case GLE_TEXTURE_NORMAL_CYL:
  341.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  342.          _gle_gc -> v3d_gen_texture = normal_cylinder_texgen_v;
  343.          _gle_gc -> n3d_gen_texture = save_normal;
  344.          break;
  345.  
  346.       case GLE_TEXTURE_VERTEX_MODEL_CYL:
  347.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  348.          _gle_gc -> v3d_gen_texture = vertex_cylinder_model_v;
  349.          _gle_gc -> n3d_gen_texture = 0x0;
  350.          break;
  351.  
  352.       case GLE_TEXTURE_NORMAL_MODEL_CYL:
  353.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  354.          _gle_gc -> v3d_gen_texture = normal_cylinder_model_v;
  355.          _gle_gc -> n3d_gen_texture = 0x0;
  356.          break;
  357.  
  358.       case GLE_TEXTURE_VERTEX_SPH:
  359.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  360.          _gle_gc -> v3d_gen_texture = vertex_sphere_texgen_v;
  361.          _gle_gc -> n3d_gen_texture = 0x0;
  362.          break;
  363.  
  364.       case GLE_TEXTURE_NORMAL_SPH:
  365.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  366.          _gle_gc -> v3d_gen_texture = normal_sphere_texgen_v;
  367.          _gle_gc -> n3d_gen_texture = save_normal;
  368.          break;
  369.  
  370.       case GLE_TEXTURE_VERTEX_MODEL_SPH:
  371.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  372.          _gle_gc -> v3d_gen_texture = vertex_sphere_model_v;
  373.          _gle_gc -> n3d_gen_texture = 0x0;
  374.          break;
  375.  
  376.       case GLE_TEXTURE_NORMAL_MODEL_SPH:
  377.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  378.          _gle_gc -> v3d_gen_texture = normal_sphere_model_v;
  379.          _gle_gc -> n3d_gen_texture = 0x0;
  380.          break;
  381.  
  382.       default:
  383.          break;
  384.    }
  385.  
  386.    /* disable texturing, and save the mode */
  387.    if (!(mode & GLE_TEXTURE_ENABLE)) {
  388.       _gle_gc -> save_bgn_gen_texture = _gle_gc -> bgn_gen_texture; 
  389.       _gle_gc -> save_n3f_gen_texture = _gle_gc -> n3f_gen_texture; 
  390.       _gle_gc -> save_n3d_gen_texture = _gle_gc -> n3d_gen_texture; 
  391.       _gle_gc -> save_v3f_gen_texture = _gle_gc -> v3f_gen_texture; 
  392.       _gle_gc -> save_v3d_gen_texture = _gle_gc -> v3d_gen_texture; 
  393.       _gle_gc -> save_end_gen_texture = _gle_gc -> end_gen_texture; 
  394.  
  395.       _gle_gc -> bgn_gen_texture = 0x0;
  396.       _gle_gc -> n3f_gen_texture = 0x0;
  397.       _gle_gc -> n3d_gen_texture = 0x0;
  398.       _gle_gc -> v3f_gen_texture = 0x0;
  399.       _gle_gc -> v3d_gen_texture = 0x0;
  400.       _gle_gc -> end_gen_texture = 0x0;
  401.    }
  402. }
  403.  
  404. /* ================== END OF FILE ========================= */
  405.